package com.fhs.trans.service;

import com.baomidou.mybatisplus.annotation.TableName;
import com.fhs.common.spring.AnnotationTypeFilterBuilder;
import com.fhs.common.spring.SpringClassScanner;
import com.fhs.common.spring.SpringContextUtil;
import com.fhs.core.trans.anno.AutoTrans;
import com.fhs.core.trans.vo.VO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author Alen
 * @date 2021-05-17 20:28
 * @since 2021-05-17 20:28
 */
public abstract class TransableRegister implements ApplicationListener<ApplicationReadyEvent> {
    private static Logger logger = LoggerFactory.getLogger(TransableRegister.class);

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        init(applicationReadyEvent);
    }

    protected  void init(ApplicationReadyEvent applicationReadyEvent){
        Set<Class<?>> entitySet = TransableRegister.scan(AutoTrans.class, getPackageNames().split(";"));
        // 遍历所有class，获取所有用@autowareYLM注释的字段
        if (entitySet != null) {
            final List<String> namespaceList = new ArrayList<>();
            for (Class<?> entity : entitySet) {
                AutoTrans autoTransSett = entity.getAnnotation(AutoTrans.class);
                if(VO.class.isAssignableFrom(entity)){
                    namespaceList.add(autoTransSett.namespace());
                    regTransable((Class<? extends VO>) entity,autoTransSett);
                    continue;
                }
                Object baseService = SpringContextUtil.getBeanByClass(entity);
                if ((baseService instanceof AutoTransAble)) {
                    namespaceList.add(autoTransSett.namespace());
                    regTransable((AutoTransAble) baseService,autoTransSett);
                    continue;
                }
            }
            apply(namespaceList);

        }
    }
    /**
     * 类扫描器
     *
     * @param annotationClass 注解
     * @param packageNames    包
     * @return 符合条件的类
     */
    public static Set<Class<?>> scan(Class<? extends Annotation> annotationClass, String[] packageNames) {
        TypeFilter entityFilter = AnnotationTypeFilterBuilder.build(annotationClass);
        SpringClassScanner entityScanner = new SpringClassScanner.Builder().typeFilter(entityFilter).build();
        for (String packageName : packageNames) {
            entityScanner.getScanPackages().add(packageName);
        }
        Set<Class<?>> entitySet = null;
        try {
            entitySet = entityScanner.scan();
        } catch (ClassNotFoundException | IOException e) {
            logger.error("包扫描错误", e);
            // log or throw runTimeExp
            throw new RuntimeException(e);
        }
        return entitySet;
    }

    /**
     * 获取要扫描的包
     * @return
     */
    protected abstract String getPackageNames();

    /**
     * 将转换器注册进框架
     * @param autoTransAble
     * @param autoTransSett
     */
    protected abstract void regTransable(AutoTransAble autoTransAble,AutoTrans autoTransSett);

    protected abstract void regTransable(Class<? extends VO> entity,AutoTrans autoTransSett);
    /**
     *使转换器生效
     * @param namespaceList
     */
    protected abstract void apply(List<String> namespaceList);
}
